<!--
 * @Author: your name
 * @Date: 2021-08-21 11:17:24
 * @LastEditTime: 2021-10-20 15:41:33
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \jincheng_mes\src\components\TaskTable.vue
-->
<template>
  <q-table
    class="q-mb-lg task_table my-sticky-last-column-table"
    :grid="$q.screen.xs"
    :rows="data"
    :columns="taskColumns"
    row-key="id"
    :rows-per-page-options="[5, 10, 25, 50, 100, 0]"
    v-model:pagination="pagination"
    :filter="filter"
    :loading="loading"
    @request="onRequest"
    binary-state-sort
    selection="multiple"
    v-model:selected="selected"
    hide-selected-banner
    :visible-columns="visibleColumns"
  >
    <template v-slot:top>
      <div class="col-12 text-white flex justify-between" :class="$q.screen.xs ? 'q-gutter-md' : ''">
        <span class="q-table__title" v-if="!$q.screen.xs">
          {{title}}({{!paging ? data.length : pagination.rowsNumber}}条)
        </span>
        <q-input outlined filled dense debounce="300" v-model="filter" :placeholder="`搜索 ${title}...`">
          <template v-slot:append>
            <q-icon v-if="filter" name="close" @click="filter = ''" class="cursor-pointer" />
            <q-icon name="search" />
          </template>
        </q-input>
        <q-btn v-if="mode === 'multiple'" icon="launch" :label="buttonLabel" color="accent" @click="doTask('-1,'+cartIds)" :disable="!cartCount">
          <q-badge color="red" floating v-if="cartCount > 0">{{cartCount}}</q-badge>
        </q-btn>
      </div>
    </template>

    <template v-slot:header-selection>
      优先
    </template>

    <template v-slot:body="props">
      <q-tr :props="props">
        <q-td>
          <q-toggle v-model="props.selected" />
        </q-td>
        <q-td :key="col.name" :props="props" v-for="col in props.cols" style="padding: 0">
          <div v-if="col.name === 'operate'" class="q-gutter-sm" style="min-width: 80px">
            <slot name="front-operate" v-bind:props="props"></slot>
            <q-btn v-if="mode === 'single'" dense size="sm" icon="launch" :label="buttonLabel" color="accent" @click="doTask('-1,'+props.row.id)" />
            <q-btn
              v-if="mode === 'multiple'"
              dense
              size="sm"
              :icon="whetherInCart(props.row) ? 'remove' : 'add'"
              :label="whetherInCart(props.row) ? '移除' : '添加'"
              color="info" @click="toggleCart(props.row)"
              :disable="!isSimilar(props.row)"
            />
            <slot name="after-operate" v-bind:props="props"></slot>
          </div>
          <slot :name="'body-'+col.name" v-bind:props="props">
            {{ col.value }}
          </slot>
        </q-td>
      </q-tr>
    </template>

    <template v-slot:item="props">
      <q-list dense class="fit shadow-1 q-mb-md q-py-md">
        <q-item>
          <q-item-section class="text-grey-8">
            <q-item-label>优先</q-item-label>
          </q-item-section>
          <q-item-section>
            <q-item-label><q-toggle v-model="props.selected" /></q-item-label>
          </q-item-section>
        </q-item>
        <q-item v-for="col in props.cols" :key="col.name">
          <q-item-section class="text-grey-8">
            <q-item-label>{{ col.label }}</q-item-label>
          </q-item-section>
          <q-item-section>
            <div v-if="col.name==='operate'" class="q-gutter-sm">
              <q-btn v-if="mode === 'single'" dense size="sm" icon="launch" :label="buttonLabel" color="accent" @click="doTask('-1,'+props.row.id)" />
              <q-btn v-if="mode === 'multiple'" dense size="sm" :icon="whetherInCart(props.row) ? 'remove' : 'add'" :label="whetherInCart(props.row) ? '移除' : '添加'" color="info" @click="toggleCart(props.row)" />
            </div>
            <q-item-label v-else>
              <slot :name="'body-'+col.name" v-bind:props="props">
                {{ col.value }}
              </slot>
            </q-item-label>
          </q-item-section>
        </q-item>
      </q-list>
    </template>
  </q-table>
</template>

<script>
import { defineComponent } from 'vue';
import { mapState, mapActions } from 'pinia';
import { useStore } from 'stores/store';

export default defineComponent({
  props: {
    type: String, // 任务类型，即 ssr/util/taskSet.js 里的那些类型
    columns: Array, // 字段配置
    mode: {
      type: String,
      default: 'single' // 单选、多选类型, single - 单选 multiple - 多选
    },
    buttonLabel: {
      type: String,
      default: '做任务' // 按钮名称
    },
    title: String, // 任务名称
    similarKey: { // 同类关键字段，只针对mode为multiple有效
      type: String,
      default: ''
    },
    paging: { // 是否分布取数据，默认全取
      type: Boolean,
      default: false
    }
  },
  emits: ['completed', 'doTask'],
  data () {
    const self = this;
    return {
      data: [],
      filter: '',
      pagination: {
        sortBy: 'id',
        descending: true,
        page: 1,
        rowsPerPage: 5
        // rowsNumber: 10
      },
      loading: false,
      selected: [],
      similarValue: '', // 同类的值
      cart: [] // 购物车
    };
  },
  mounted () {
    if (this.$route.query.back === 'true') {
      this.filter = this.$q.localStorage.getItem(`${this.pageKeyWord}TaskFilter`) || '';
    }

    this.onRequest({
      pagination: this.pagination,
      filter: this.filter
    });
  },
  methods: {
    ...mapActions(useStore, ['saveSearchParam']),
    onRequest (props) {
      if (!this.type) return;

      let req;
      if (this.paging) {
        if (this.pagination.rowsNumber === undefined) {
          this.$set(this.pagination, 'rowsNumber', 10);
          // this.pagination.rowsNumber = 0;
        }
        const { page, rowsPerPage, descending } = props.pagination;

        const filter = props.filter;
        const startRow = (page - 1) * rowsPerPage;
        const count = rowsPerPage;

        req = {
          paging: { startRow, count, filter, descending, columns: this.columns.map(v => v.field).filter(v => !!v) },
          type: this.type
        }
      } else {
        // delete this.pagination.rowsNumber;
        req = { type: this.type };
      }

      this.loading = true;
      const self = this;

      const defaultImage = (rows) => {
        const imageFields = ['goods_images', 'part_images', 'material_images', 'images']; // 后续有新的字段名，添加到这个数组中
        rows.forEach(row => {
          for (const field of imageFields) {
            if (row[field] && typeof row[field] === 'string') {
              row[field] = JSON.parse(row[field]);
            }
            // 无图片转成默认图片
            if (!row[field] || row[field].length === 0) {
              row[field] = self.defaultImg;
            }
          }
          row._cart = false; // 购物车标记
        });

        self.selected = rows.filter(v => v.prior); // 取出优先的数据
        self.$nextTick(() => {
          self.loading = false;
          self.$emit('completed', rows); // 发送数据提取完成事件
        });
      };

      this.$axios.post('/c/task/getSingleTask', req)
        .then(({ data }) => {
          if (self.paging) {
            defaultImage(data[self.type].data);

            self.data = data[self.type].data;
            self.pagination.rowsNumber = data[self.type].rowsNumber;
            // this.$set(this.pagination, 'rowsNumber', data[self.type].rowsNumber);
            self.pagination.page = props.pagination.page;
            self.pagination.rowsPerPage = props.pagination.rowsPerPage;
            self.pagination.sortBy = props.pagination.sortBy;
            self.pagination.descending = props.pagination.descending;
          } else {
            defaultImage(data[self.type]);
            self.data = data[self.type];
          }
        });
    },
    doTask (ids) {
      this.$emit('doTask', ids);
    },
    toggleCart (row) { // 添加 移除采购车
      /* row._cart = !row._cart;

      if (row._cart && this.similarKey && !this.similarValue) { // 第一个添加
        this.similarValue = row[this.similarKey]; // 存储用于检查同类的值
      } else if (!row._cart && this.similarKey && this.data.filter(v => v._cart).length === 0) { // 最后一个移除
        this.similarValue = '';
      }

      this.data = JSON.parse(JSON.stringify(this.data)); // 只有这样才监听得到数组发生变化 */

      const idx = this.cart.findIndex(v => v.id == row.id);
      if (idx < 0) {
        this.cart.push(row); // 加入
        if (this.cart.length === 1 && this.similarKey && !this.similarValue) { // 第一个添加
          this.similarValue = row[this.similarKey]; // 存储用于检查同类的值
        }
      } else {
        this.cart.splice(idx, 1); // 剔除
        if (this.cart.length === 0 && this.similarKey) { // 最后一个移除
          this.similarValue = '';
        }
      }
    },
    whetherInCart (row) { // 是否在购物车里
      return this.cart.filter(v => v.id == row.id).length > 0;
    },
    getTaskData () { // 获取任务数据
      return this.data;
    },
    getTaskCount () { // 获取任务数量
      return this.data.length;
    },
    isSimilar (row) { // 是否同类
      if (this.mode === 'multiple' && this.similarKey && this.similarValue) {
        return row[this.similarKey] == this.similarValue;
      } else {
        return true;
      }
    },
    saveState () {
      const state = {};
      state[this.type] = {
        pagination: this.pagination,
        filter: this.filter
      };
      this.saveSearchParam(state);
    },
    restoreState () {
      if (this.searchParam[this.type]) {
        this.pagination = this.searchParam[this.type].pagination;
        this.filter = this.searchParam[this.type].filter;
      }
    },
    refreshTask () { // 刷新任务数据
      this.onRequest({
        pagination: this.pagination,
        filter: this.filter
      });
    },
    filterData (word) {
      this.filter = word;
      this.refreshTask();
    }
  },
  computed: {
    ...mapState(useStore, ['dictObj', 'defaultImg', 'searchParam']),
    cartCount () { // 购物车物料数
      // return this.data.filter(v => v._cart).length;
      return this.cart.length;
    },
    cartIds () { // 待入购物车任务的ids
      // return this.data.filter(v => v._cart).map(v => v.id).join(',');
      return this.cart.map(v => v.id).join(',');
    },
    taskColumns () { // 增加操作字段
      if (this.columns.filter(v => v.name === 'operate').length == 0) {
        return [...this.columns, { name: 'operate', label: '操作', align: 'center' }];
      } else {
        return [...this.columns];
      }
    },
    pageKeyWord () {
      const path = this.$route.path.split('/');
      return path.length > 2 ? this.$route.path.split('/')[2] : '';
    },
    visibleColumns () {
      return this.taskColumns.filter(v => v.visible || v.visible === undefined).map(v => v.name);
    }
  },
  watch: {
    selected (val) {
      const self = this;
      if (!self.loading) {
        let priorityTasks = [];
        if (val.length > 0) {
          priorityTasks = priorityTasks.concat(val.map(v => { return { task_type: self.type, task_id: v.id } }));
        } else {
          priorityTasks.push({ task_type: this.type, task_id: '' });
        }

        this.$axios.post('/c/task/priorityTasks', { priorityTasks })
          .then(res => {
          });
      }
    },
    filter (val) {
      this.$q.localStorage.set(`${this.pageKeyWord}TaskFilter`, val);
    }
  }
});
</script>

<style lang="scss">
.task_table .q-table__top {
  background-color: #0097a7;
}

</style>
